package pide.core;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;


public class Configuration {

	
	public File file = new File("configuration.props");
	
	private static Configuration instance = null;	
	private Map<String,String> props = new TreeMap<>();

	public final static String COMMENT_MARKER = "#";
	
	private Configuration(){
		try {
			load();
		} catch (IOException e) {			
			e.printStackTrace();
		}
	}
	
	public static Configuration getInstance()
	{
		if(instance==null)
			instance  = new Configuration();
		return instance;
	}
	
	public void addComment(String c)
	{
		props.put(COMMENT_MARKER+c, null);
		try {
			save();
		} catch (FileNotFoundException e) {			
			e.printStackTrace();
		}
	}
	
	public void add(String k,String v)
	{
		props.put(k, v);
		try {
			save();
		} catch (FileNotFoundException e) {			
			e.printStackTrace();
		}
	}
	
	public void remove(String k)
	{
		props.remove(k);
		try {
			save();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public void validate()
	{
		try {
			load();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public String get(String k)
	{
		return props.get(k);
	}
	
	public Integer getInt(String k)
	{
		return Integer.parseInt(props.get(k));
	}
	
	public Double[][] get2DArrayDouble(String k) 
	{
		String str = props.get(k).trim();
		str = str.substring(1,str.length()-1); //remove [ , ] characters
		
		Integer nCols = null;
		
		String [] rows = str.split(";");
		Double[][] matrix = new Double[rows.length][];
		for(int i = 0; i < rows.length;i++)
		{
			String [] cols = rows[i].split(",");
			if(nCols!=null && cols.length!=nCols)
			{
				try {
					throw new Exception("Different cols size "+cols.length+"!="+nCols);
				} catch (Exception e) {					
					e.printStackTrace();
				}				 
			}
			nCols=cols.length;
			
			matrix[i]=new Double[nCols];
			for(int j = 0;j<cols.length;j++)
			{
				matrix[i][j]=Double.parseDouble(cols[j]);
			}
		}
		
		return matrix;
		
	}
	
	
	public String[] getArray(String k) 
	{
		String str = props.get(k).trim();
		str = str.substring(1,str.length()-1); 
		return str.split(",");
		
		
	}
	
	public Double getDouble(String k)
	{
		return Double.parseDouble(props.get(k));
	}
	public boolean getBoolean(String k)
	{
		return props.get(k).equalsIgnoreCase("true");
	}
	
	public Map<String,String> getByPrefix(String prefix)
	{
		Map<String,String> map = new HashMap<>();
		for(String key:props.keySet())
		{
			if(key.startsWith(prefix))
				map.put(key,props.get(key));
		}
		return map;
	}
	
	public Map<String,String> getAll()
	{
		return props;
	}
	
	private void load() throws IOException 
	{
		if(file.exists())
		{
			BufferedReader br = new BufferedReader(new FileReader(file));
			String line = "";
			
			while((line=br.readLine())!=null)
				{
					if(line.trim().length()==0)	continue;
					
					if(!line.startsWith(COMMENT_MARKER))
					{
						String[] array = line.split("=");
						props.put(array[0], array[1]);
					}
					else
					{
						props.put(line,null);
					}
				}
			
			br.close();
		}
		
	}
	
	private void save() throws FileNotFoundException
	{
		PrintWriter pw = new PrintWriter(file);
		for(String key:props.keySet())
		{
			String value = props.get(key);
			if(value!=null)
				pw.println(key+"="+value);
			else
				pw.println(key);
		}
		pw.close();
	}
	
	
	
	@Override
	public String toString() {
		String str ="";
		for(String key:props.keySet())
		{
			String value = props.get(key);
			if(value!=null)
				str+=key+"="+value+"\n";
			else
				str+=key+" [ COMMENT ]\n";
		}
		return str;
	}
	
	
	
	
}
